home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 4 code / IIgs Printer Driver / PICTER.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-08-20  |  63.3 KB  |  2,086 lines  |  [TEXT/pdos]

  1. *****************************************************************
  2. *
  3. *  Sample Printer Driver
  4. *
  5. *  This sample driver does simple communication with a port driver
  6. *  and saves a QD Pict of the pages to be imaged to the
  7. *  */SYSTEM/DRIVERS folder.
  8. *
  9. *  By Matt Deatherage
  10. *
  11. *  Copyright 1990, Apple Computer, Inc.  All rights reserved.
  12. *
  13. *
  14. *  Revision history:
  15. *
  16. *  7/15/90   Version 1.0
  17. *
  18. *  First take.  All routines present and functional.
  19. *
  20. *  8/07/90   Version 1.1
  21. *
  22. *  Code rearranged and a MAKEFILE added.  PrDefault and PrValidate rewritten
  23. *  to behave themselves instead of tinkling in the print record.
  24. *
  25. *  8/18/90   Version 1.2
  26. *
  27. *  The Dave version.  Incorporated his comments.
  28. *
  29. *****************************************************************
  30.  
  31.              mcopy picter.macros
  32.              copy  drvrequates.asm      ; all of our equates
  33.              copy  2/ainclude/e16.quickdraw
  34.              copy  2/ainclude/e16.window
  35.              copy  2/ainclude/e16.print
  36.  
  37. **********************************************************************
  38. *
  39. * PictDriver main entry point
  40. *
  41. *  Inputs:   Printer driver entry - precomputed X register
  42. *
  43. * Outputs:   None - branches to EndOurWorld in each routine
  44. *
  45. **********************************************************************
  46.  
  47. Picter       START
  48.  
  49. ;
  50. ;  First, the standard new printer driver header
  51. ;
  52.  
  53.              dc    i2'0'                ; new style driver
  54.              dc    i2'(ListEnd-PrDriverList)/4'
  55.  
  56.              jsr   MakeOurWorld
  57.  
  58. ;
  59. ;  After setting things up, we have the following information in the
  60. ;  registers:
  61. ;
  62. ;  X = precomputed jump table offset to the routine to call
  63. ;  A = any error code from establishing our world (memory errors, etc.)
  64. ;  carry flag = set if we had to create our DP.
  65. ;
  66. ;  If the carry is set and A is non-zero, there was an error and our world
  67. ;  does not exist.  We can't handle this here generically because each
  68. ;  routine has different parameters to pull off the stack.  Instead, we
  69. ;  pass this register information to each of the routines for proper error
  70. ;  handling.  For example, if we store stuff between calls on our direct page,
  71. ;  it's an error for PrOpenPage to get the carry set.  That would mean that
  72. ;  the driver was unloaded after PrOpenDoc, and this isn't good.
  73. ;
  74.  
  75.              jmp   (PrDriverList,x)     ; go do the routine
  76. ;                                         (all routines have to be in this seg)
  77.  
  78.  
  79. PrDriverList dc    i4'PrDefault'        ; $0913
  80.              dc    i4'PrValidate'       ; $0A13
  81.              dc    i4'PrStlDialog'      ; $0B13
  82.              dc    i4'PrJobDialog'      ; $0C13
  83.              dc    i4'PrDriverVer'      ; $2313
  84.              dc    i4'PrOpenDoc'        ; $0E13
  85.              dc    i4'PrCloseDoc'       ; $0F13
  86.              dc    i4'PrOpenPage'       ; $1013
  87.              dc    i4'PrClosePage'      ; $1113
  88.              dc    i4'PrPicFile'        ; $1213
  89.              dc    i4'PrReserved'       ; $1313 is reserved, so get out
  90.              dc    i4'PrError'          ; $1413
  91.              dc    i4'PrSetError'       ; $1513
  92.              dc    i4'GetDeviceName'    ; $1713
  93.              dc    i4'PrPixelMap'       ; $0D13
  94.              dc    i4'PrGetPrinterSpecs' ; $1813
  95.              dc    i4'PrGetPgOrientation' ;$3813
  96. ListEnd      anop
  97.  
  98.              END
  99.  
  100. **********************************************************************
  101. *
  102. * PrDefault fills the given handle with this driver's default print
  103. * record, which depends on the current screen resolution.
  104. *
  105. *  Inputs:   Print record handle on the stack
  106. *
  107. * Outputs:   None
  108. *
  109. **********************************************************************
  110.  
  111. PrDefault    START
  112.              USING PicterData
  113.  
  114.              ldy   #4
  115.              jsr   CheckTheWorld
  116.  
  117. ; Parameters start at ParamStart,s (see MakeOurWorld)
  118.  
  119.              lda   ParamStart,s
  120.              sta   <PrRecHndl
  121.              lda   ParamStart+2,s
  122.              sta   <PrRecHndl+2
  123.  
  124.              pei   <PrRecHndl+2         ; doing this separately avoids changing
  125.              pei   <PrRecHndl           ; the stack offsets - either way's fine
  126.              _CheckHandle
  127.              bcc   HandleOK
  128.              lda   #noPrintRecord       ; change it to a print manager error
  129.              brl   DefOut               ; get out of PrDefault
  130.  
  131. HandleOK     pushlong #DfPRecBase       ; default print record base addr
  132.              pei   <PrRecHndl+2
  133.              pei   <PrRecHndl
  134.              pushlong #PrRecSize
  135.              _PtrToHand                 ; fill in the print record
  136.  
  137.              jsr   CalcMetrics          ; fix up the metrics
  138.  
  139.              lda   #0                   ; no error
  140.  
  141. DefOut       tax
  142.              ldy   #4
  143.              brl   EndOurWorld
  144.  
  145.  
  146.              END
  147.  
  148. **********************************************************************
  149. *
  150. * PrValidate looks at those values which could be invalid for our
  151. * printer and if they are invalid, corrects them.
  152. *
  153. *  Inputs:   Word space for boolean result
  154. *            Print record handle on the stack
  155. *
  156. * Outputs:   recAdjusted flag
  157. *
  158. **********************************************************************
  159.  
  160. PrValidate   START
  161.              USING PicterData
  162.  
  163.              ldy   #4
  164.              jsr   CheckTheWorld
  165.  
  166. ; Parameters start at ParamStart,s (see MakeOurWorld)
  167.  
  168.              lda   ParamStart,s
  169.              sta   <PrRecHndl
  170.              lda   ParamStart+2,s
  171.              sta   <PrRecHndl+2
  172.  
  173.              pei   <PrRecHndl+2         ; doing this separately avoids changing
  174.              pei   <PrRecHndl           ; the stack offsets - either way's fine
  175.              _CheckHandle
  176.              bcc   OK0
  177.              ldx   #noPrintRecord       ; change it to a print manager error
  178.              ldy   #4                   ; number of bytes to remove
  179.              brl   ValOut2              ; get out of PrValidate
  180.  
  181. ;
  182. ; We use the same value used by CalcMetrics - RectChanged - to indicate
  183. ; if the print record has changed any while validating.
  184. ;
  185.  
  186. OK0          stz   <RectChanged
  187.  
  188.              ldy   #4
  189.              lda   [PrRecHndl],y
  190.              sta   <temp                ; save it on direct page
  191.              ora   #$8000               ; lock it
  192.              sta   [PrRecHndl],y
  193.              dey
  194.              dey
  195.              lda   [PrRecHndl],y
  196.              sta   <PrRecPtr+2
  197.              lda   [PrRecHndl]
  198.              sta   <PrRecPtr            ; and dereference it
  199.  
  200.              ldy   #oprInfo+oiDev       ; the iDev parameter
  201.              lda   [PrRecPtr],y         ; get the iDev field
  202.              cmp   #OuriDev             ; is it ours?
  203.              beq   OK1
  204.              brl   doDefault
  205.  
  206. OK1          ldy   #oprInfo+oiVRes
  207.              lda   [PrRecPtr],y
  208.              cmp   #ouriVRes            ; is it ours?
  209.              beq   OK2
  210.              lda   #ouriVRes
  211.              sta   [PrRecPtr],y
  212.              inc   <RectChanged         ; note we did something
  213.  
  214. OK2          pha
  215.              _GetMasterSCB
  216.              pla
  217.              sta   <MasterSCB
  218.              and   #$0080
  219.              beq   Test320
  220.  
  221. Test640      ldy   #oprInfo+oiHRes
  222.              lda   [PrRecPtr],y
  223.              cmp   #ouriHRes640
  224.              beq   OK3
  225.              lda   #ourIHRes640
  226.              sta   [PrRecPtr],y
  227.              inc   <RectChanged
  228. OK3          bra   doneHRes
  229.  
  230. Test320      ldy   #oprInfo+oiHRes
  231.              lda   [PrRecPtr],y
  232.              cmp   #ouriHRes320
  233.              beq   doneHRes
  234.              lda   #ouriHRes320
  235.              sta   [PrRecPtr],y
  236.              inc   <RectChanged
  237.  
  238. doneHRes     jsr   CalcMetrics
  239.              lda   <RectChanged
  240.              cmp   #$FFFF
  241.              beq   DoDefault
  242.  
  243.              ldy   #oprStl+owDev
  244.              lda   [PrRecPtr],y
  245.              and   #$FFFF-AppleBitMask  ; don't care about Apple's bits
  246.              cmp   #OurwDev
  247.              beq   CheckMethod
  248.              lda   [PrRecPtr],y
  249.              and   #AppleBitMask        ; leave Apple's reserved bits set
  250.              ora   #OurwDev
  251.              sta   [PrRecPtr],y
  252.              inc   <RectChanged
  253.  
  254.  
  255. CheckMethod  ldy   #oprJob+objDocLoop
  256.              lda   [PrRecPtr],y
  257.              and   #$00FF               ; only one byte, please
  258.              cmp   #OurBJDocLoop        ; should be spool-only
  259.              beq   ZeroIdleProc
  260.              lda   [PrRecPtr],y
  261.              and   #$FF00               ; clear out low byte
  262.              ora   #OurBJDocLoop        ; or in the low byte
  263.              sta   [PrRecPtr],y
  264.              inc   <RectChanged
  265.  
  266. ZeroIdleProc ldy   #oprJob+opIdleProc   ; always zero this out
  267.              lda   #0
  268.              sta   [PrRecPtr],y
  269.              iny
  270.              iny
  271.              sta   [PrRecPtr],y
  272.  
  273.              lda   <RectChanged         ; this is zero if the rects were OK
  274.              beq   ItsZero
  275.              lda   #1
  276. ItsZero      sta   ParamStart+4,s       ; so use it as changed flag
  277.              ldx   #0
  278.  
  279. ValOut       lda   <Temp
  280.              ldy   #4                   ; remove four bytes of parameters
  281.              sta   [<PrRecHndl],y       ; and it's an index, too!  At no cost!
  282. ValOut2      brl   EndOurWorld
  283.  
  284. doDefault    pei   <PrRecHndl+2
  285.              pei   <PrRecHndl
  286.              _PrDefault
  287.              tax                        ; save the error code
  288.              lda   #TRUE
  289.              sta   ParamStart+4,s       ; set the changed flag
  290.  
  291.              bra   ValOut
  292.  
  293.              END
  294.  
  295. **********************************************************************
  296. *
  297. * PrStlDialog conducts the "page setup" dialog.
  298. *
  299. *  Inputs:   Word space for confirmation flag
  300. *            Print record handle
  301. *
  302. * Outputs:   confirmation flag
  303. *
  304. **********************************************************************
  305.  
  306. PrStlDialog  START
  307.              USING PicterData
  308.  
  309.              ldy   #4
  310.              jsr   CheckTheWorld
  311.  
  312.              lda   ParamStart,s
  313.              sta   <PrRecHndl
  314.              lda   ParamStart+2,s
  315.              sta   <PrRecHndl+2
  316.  
  317.              ldy   #4
  318.              lda   [PrRecHndl],y
  319.              sta   <temp                ; save old handle attributes
  320.              ora   #$8000               ; lock the print record handle
  321.              sta   [PrRecHndl],y
  322.              dey
  323.              dey
  324.              lda   [PrRecHndl],y
  325.              sta   <PrRecPtr+2
  326.              lda   [PrRecHndl]
  327.              sta   <PrRecPtr            ; and dereference it
  328.  
  329.              jsr   ConductStyleDialog
  330.              pha                        ; save for a moment
  331.  
  332.              lda   <temp
  333.              ldy   #4
  334.              sta   [<PrRecHndl],y       ; restore the handle attributes
  335.  
  336.              pla                        ; restore the dialog result
  337.              sta   ParamStart+4,s       ; space for result
  338.  
  339.              ldy   #4
  340.              ldx   #0
  341.              brl   EndOurWorld
  342.  
  343.              END
  344.  
  345. **********************************************************************
  346. *
  347. * PrJobDialog conducts the "print" dialog.
  348. *
  349. *  Inputs:   Word space for confirmation flag
  350. *            Print record handle
  351. *
  352. * Outputs:   confirmation flag
  353. *
  354. **********************************************************************
  355.  
  356. PrJobDialog  START
  357.              USING PicterData
  358.  
  359.              ldy   #4
  360.              jsr   CheckTheWorld
  361.  
  362.              lda   ParamStart,s
  363.              sta   <PrRecHndl
  364.              lda   ParamStart+2,s
  365.              sta   <PrRecHndl+2
  366.  
  367.              ldy   #4
  368.              lda   [PrRecHndl],y
  369.              sta   <temp                ; save handle attributes
  370.              ora   #$8000               ; lock the print record handle
  371.              sta   [PrRecHndl],y
  372.              dey
  373.              dey
  374.              lda   [PrRecHndl],y
  375.              sta   <PrRecPtr+2
  376.              lda   [PrRecHndl]
  377.              sta   <PrRecPtr            ; and dereference it
  378.  
  379.              jsr   ConductJobDialog
  380.              pha                        ; save for a moment
  381.  
  382.              lda   <temp
  383.              ldy   #4
  384.              sta   [<PrRecHndl],y       ; restore the handle attributes
  385.  
  386.              pla                        ; restore the dialog result
  387.              sta   ParamStart+4,s       ; space for result
  388.  
  389.              ldy   #4
  390.              ldx   #0
  391.              brl   EndOurWorld
  392.  
  393.              END
  394.  
  395. **********************************************************************
  396. *
  397. * PrPixelMap prints all or part of the specified pixel map.  For our
  398. * picter driver, we create a picture with the pixel map in it and
  399. * write it to the disk.
  400. *
  401. *  Inputs:   srcLocPtr, srcRectPtr, colorFlag (ignored)
  402. *
  403. * Outputs:   None
  404. *
  405. **********************************************************************
  406.  
  407. PrPixelMap   START
  408.              USING PicterData
  409.  
  410.              ldy   #10                  ; 10 bytes of parameters
  411.              jsr   CheckTheWorld
  412.  
  413. ;
  414. ;  We don't use a port driver here, but normally we would make sure it's
  415. ;  safe to print at this point.
  416. ;
  417. ;            pha                        ; space for result
  418. ;            _PrDevIsItSafe             ; is the port around?
  419. ;            pla                        ; the result
  420. ;            bne   OKToPrint            ; the port is safe
  421. ;            lda   #PortNotOn           ; error $1302
  422. ;            sta   <OurError
  423. ;            brl   PixMapOut            ; get out of here
  424. ;
  425.  
  426. OKToPrint    pha
  427.              pha                        ; space for result
  428.              _GetPort
  429.              pulllong <OldPort          ; save it
  430.  
  431.              pha
  432.              pha
  433.              _GetCursorAdr
  434.              pulllong <OldCursor        ; save this too
  435.  
  436.              _WaitCursor                ; watch time
  437.  
  438.              stz   <OurError            ; clear this out
  439.  
  440. ;
  441. ;  We don't create a new print record handle because we don't have to
  442. ;  use it to communicate with the caller and we don't need it in this case.
  443. ;  In many cases it will be easier for PrPixelMap to allocate a print
  444. ;  record and call the deferred printing code.  Do whichever suits your
  445. ;  needs best.
  446. ;
  447.  
  448.              pha
  449.              pha                        ; space for result
  450.              pushlong #GrafPortSize
  451.              pei   <MyID
  452.              pea   $C000                ; locked and fixed
  453.              pushlong #0
  454.              _NewHandle
  455.              tax                        ; save the error code
  456.              pulllong <PortHandle       ; save the handle
  457.              txa                        ; restore the error code
  458.              bcs   PixMapOut
  459.  
  460.              lda   [<PortHandle]
  461.              sta   <PortPointer
  462.              ldy   #2
  463.              lda   [<PortHandle],y
  464.              sta   <PortPointer+2
  465.  
  466.              pei   <PortPointer+2
  467.              pei   <PortPointer
  468.              _OpenPort                  ; set it up as a grafPort
  469.  
  470. DoPicture    clc
  471.              lda   <PortPointer
  472.              adc   #oboundsRect
  473.              sta   <RectPointer
  474.              lda   <PortPointer+2
  475.              adc   #0
  476.              sta   <RectPointer+2
  477.  
  478.              jsr   OpenPICTFile         ; create the new picture and file
  479.              bcs   PixMapOut2
  480.  
  481. ;
  482. ;  Our parameters start at ParamStart,s and will change as we push duplicate
  483. ;  copies of them on the stack, so the offsets stay the same.
  484. ;
  485.  
  486.              lda   ParamStart+8,s       ; high word of srcLocPtr
  487.              pha
  488.              lda   ParamStart+8,s       ; low word of srcLocPtr
  489.              pha
  490.              lda   ParamStart+8,s       ; high word of srcRectPtr
  491.              pha
  492.              lda   ParamStart+8,s       ; low word of srcRectPtr
  493.              pha
  494.              lda   #0
  495.              pha                        ; startX
  496.              pha                        ; startY
  497.              pea   modeCopy
  498.              _PPToPort                  ; it's now in the picture
  499.  
  500.              jsr   ClosePICTFile        ; write it and close it
  501.              bcs   PixMapOut2
  502.              lda   #0                   ; no error
  503.  
  504. ;
  505. ;  Note that if we were really printing, we'd want to form feed at the
  506. ;  end of the pixel map - one job per page, please
  507. ;
  508.  
  509. ;
  510. ;  PixMapOut2 gets out of here after taking care of all the stuff we
  511. ;  changed around and allocated (cursors, grafPorts, etc.)
  512. ;
  513.  
  514. PixMapOut2   pha                        ; save error code on stack
  515.  
  516.              pei   <OldPort+2
  517.              pei   <OldPort
  518.              _SetPort
  519.  
  520.              pei   <PortPointer+2
  521.              pei   <PortPointer
  522.              _ClosePort                  ; always close what you open
  523.  
  524.              pei   <PortHandle+2
  525.              pei   <PortHandle
  526.              _DisposeHandle
  527.  
  528.              pei   <OldCursor+2
  529.              pei   <OldCursor
  530.              _SetCursor
  531.  
  532.              pla                        ; put error code back in A
  533.  
  534. PixMapOut    tax
  535.              ldy   #10                  ; 10 bytes to pull
  536.              brl   EndOurWorld
  537.  
  538.              END
  539.  
  540. **********************************************************************
  541. *
  542. * PrOpenDoc prepares us for the print loop.  We set up some parameters
  543. * for the loop and get ready for a grand old time.
  544. *
  545. *  Inputs:   Space for returned GrafPort
  546. *            Pointer to printing GrafPort (or NIL to allocate one)
  547. *            Print record handle
  548. *
  549. * Outputs:   Pointer to the printing GrafPort
  550. *
  551. **********************************************************************
  552.  
  553. PrOpenDoc    START
  554.              USING PicterData
  555.  
  556.              ldy   #8
  557.              jsr   CheckTheWorld
  558.  
  559. ;
  560. ;  We don't use a port driver here, but normally we would make sure it's
  561. ;  safe to print at this point.
  562. ;
  563. ;            pha                        ; space for result
  564. ;            _PrDevIsItSafe             ; is the port around?
  565. ;            pla                        ; the result
  566. ;            bne   OKToPrint            ; the port is safe
  567. ;            lda   #PortNotOn           ; error $1302
  568. ;            sta   <OurError
  569. ;            brl   OpenDocOut           ; get out of here
  570. ;
  571.  
  572. OKToPrint    pha
  573.              pha                        ; space for result
  574.              _GetPort
  575.              pulllong <OldPort          ; save the current port
  576.  
  577.              pha
  578.              pha
  579.              _GetCursorAdr
  580.              pulllong <OldCursor        ; save the old cursor
  581.  
  582.              _WaitCursor                ; note this may take a while
  583.  
  584.              stz   <OurError            ; clear out the internal error variable
  585.  
  586.              pha                        ; space for result
  587.              lda   ParamStart+8,s       ; high word of print record handle
  588.              pha
  589.              lda   ParamStart+8,s       ; low word
  590.              pha
  591.              _PrValidate                ; check out the print record
  592.              pla                        ; like I care if it changed...
  593.  
  594.              jsr   StartStatusMessage   ; initialize our little box of fun
  595.  
  596.              lda   #PrOpenDocMsg
  597.              sta   <ParamLongA
  598.              lda   #PrOpenDocMsg|-16
  599.              sta   <ParamLongA+2
  600.              jsr   StatusMessage        ; display our OpenDoc message
  601.  
  602.              lda   ParamStart,s
  603.              ora   ParamStart+2,s       ; is this NIL?
  604.              beq   GetGrafPort          ; yes, allocate a graf port
  605.              lda   ParamStart,s
  606.              sta   <PortPointer
  607.              lda   ParamStart+2,s
  608.              sta   <PortPointer+2       ; put it on direct page
  609.              stz   <WeGotPort           ; initialize this to FALSE
  610.              bra   GotGrafPort
  611.  
  612. GetGrafPort  pha
  613.              pha                        ; space for result
  614.              pushlong #GrafPortSize
  615.              pei   <MyID
  616.              pushword #$C000            ; locked and fixed
  617.              lda   #0
  618.              pha
  619.              pha                        ; no location
  620.              _NewHandle
  621.              tax                        ; save error code
  622.              pulllong <PortHandle
  623.              stx   <OurError
  624.              bcs   OpenDocOut           ; no printing for us
  625.  
  626.              ldy   #2
  627.              lda   [PortHandle],y
  628.              sta   <PortPointer+2
  629.              lda   [PortHandle]
  630.              sta   <PortPointer
  631.  
  632.              pei   <PortPointer+2
  633.              pei   <PortPointer
  634.              _OpenPort
  635.  
  636.              lda   #1
  637.              sta   <WeGotPort
  638.  
  639. GotGrafPort  anop
  640.  
  641.              stz   <PageNumber          ; clear this out
  642.  
  643.              lda   <PortPointer
  644.              sta   ParamStart+8,s       ; the return parameter
  645.              lda   <PortPointer+2
  646.              sta   ParamStart+10,s
  647.  
  648. OpenDocOut   ldx   <OurError
  649.              ldy   #8
  650.              brl   EndOurWorld
  651.  
  652.              END
  653.  
  654. **********************************************************************
  655. *
  656. * PrCloseDoc undoes everything done by PrOpenDoc except the cursor
  657. * and restoring the current port.
  658. *
  659. *  Inputs:   The printing grafPort pointer
  660. *
  661. * Outputs:   None.
  662. *
  663. **********************************************************************
  664.  
  665. PrCloseDoc   START
  666.  
  667. ;
  668. ;  In this routine, it is very important that the direct page have
  669. ;  already been set up.  If it got set up on the entrance to this call,
  670. ;  some idiot unloaded the printer driver in the middle of the print
  671. ;  loop and all our stuff is invalid.
  672. ;
  673.  
  674.              bcc   Whew                 ; nothing's wrong yet
  675.              ldy   #4                   ; 4 bytes of parameters
  676.              ldx   #PrBozo              ; PrBozo error
  677.              brl   EndOurWorld
  678.  
  679. Whew         lda   <OurError
  680.              cmp   #PortNotOn           ; is this the error
  681.              bne   Whew2                ; still good
  682.              ldy   #4
  683.              ldx   #0                   ; don't return error, just return
  684.              brl   EndOurWorld
  685.  
  686. Whew2        lda   ParamStart,s
  687.              sta   <PortPointer
  688.              lda   ParamStart+2,s
  689.              sta   <PortPointer+2
  690.  
  691.              pei   <OldPort+2
  692.              pei   <OldPort
  693.              _SetPort                   ; the previous port is now restored
  694.  
  695.              pei   <PortPointer+2
  696.              pei   <PortPointer
  697.              _ClosePort
  698.  
  699.              lda   <WeGotPort           ; did we allocate this?
  700.              beq   CloseDialog
  701.  
  702.              pei   <PortHandle+2
  703.              pei   <PortHandle
  704.              _DisposeHandle
  705.  
  706. CloseDialog  jsr   FinishStatusMessage
  707.  
  708. CloseDocOut  ldx   #0
  709.              ldy   #4
  710.              brl   EndOurWorld
  711.  
  712.              END
  713.  
  714. **********************************************************************
  715. *
  716. * PrOpenPage captures, somehow, an image of a page to be printed if
  717. * and only if the page falls within the range of pages to be printed
  718. * as specified in the print record.  We do this with QuickDraw pictures,
  719. * an excellent choice since they're what we're writing to disk anyway.
  720. *
  721. *  Inputs:   Pointer to the printing grafPort
  722. *            Pointer to a pageFrame rectangle
  723. *
  724. * Outputs:   None
  725. *
  726. **********************************************************************
  727.  
  728. PrOpenPage   START
  729.              USING PicterData
  730. ;
  731. ;  In this routine, it is very important that the direct page have
  732. ;  already been set up.  If it got set up on the entrance to this call,
  733. ;  some idiot unloaded the printer driver in the middle of the print
  734. ;  loop and all our stuff is invalid.
  735. ;
  736.  
  737.              bcc   Whew                 ; nothing's wrong yet
  738.              ldy   #8                   ; 8 bytes of parameters
  739.              ldx   #PrBozo              ; PrBozo error
  740.              brl   EndOurWorld
  741.  
  742. Whew         lda   <OurError            ; return if any error is here
  743.              beq   Whew2                ; still good
  744.              ldy   #8
  745.              ldx   #0                   ; don't return error, just return
  746.              brl   EndOurWorld
  747.  
  748. Whew2        inc   <PageNumber          ; we're on the next page now
  749.  
  750.              ldy   #4
  751.              lda   [PrRecHndl],y
  752.              sta   <Temp2               ; save handle attributes
  753.              ora   #$8000               ; lock the print record handle
  754.              sta   [PrRecHndl],y
  755.              dey
  756.              dey
  757.              lda   [PrRecHndl],y
  758.              sta   <PrRecPtr+2
  759.              lda   [PrRecHndl]
  760.              sta   <PrRecPtr            ; and dereference it
  761.  
  762.              lda   <PageNumber
  763.              ldy   #oprJob+oiFstPage
  764.              cmp   [<PrRecPtr],y
  765.              bge   Whew3                ; Dave would rather see BCS - tough
  766.              lda   #0                   ; no error to be out of page range
  767.              brl   OpenPageOut          ; sorry, no printing
  768. Whew3        ldy   #oprJob+oiLstPage
  769.              dec   a                    ; make it one smaller
  770.              cmp   [<PrRecPtr],y
  771.              blt   Whew4                ; Dave would rather see BCC - tough
  772.              lda   #0                   ; no error to be out of page range
  773.              brl   OpenPageOut          ; don't print
  774.  
  775. Whew4        lda   #PrOpenPageMsg
  776.              sta   <ParamLongA
  777.              lda   #PrOpenPageMsg|-16
  778.              sta   <ParamLongA+2
  779.              jsr   StatusMessage        ; PrOpenPage message
  780.  
  781.              lda   ParamStart+4,s
  782.              sta   <PortPointer
  783.              lda   ParamStart+6,s
  784.              sta   <PortPointer+2
  785.  
  786.              pei   <PortPointer+2
  787.              pei   <PortPointer
  788.              _SetPort                   ; it's now current
  789.  
  790.              pei   <PortPointer+2
  791.              pei   <PortPointer
  792.              _InitPort                  ; reset it to the default
  793.  
  794.              pushlong #LocInfoSpace     ; space for LocInfo games
  795.              _GetPortLoc
  796.  
  797.              stz   LocInfoSpace+8
  798.              stz   LocInfoSpace+10
  799.              stz   LocInfoSpace+12      ; zero out the boundsRect so
  800.              stz   LocInfoSpace+14      ; no drawing occurs
  801.  
  802.              pushlong #LocInfoSpace
  803.              _SetPortLoc
  804.  
  805.              lda   ParamStart,s
  806.              ora   ParamStart+2,s       ; is the frameRect NIL?
  807.              beq   getrPage             ; if so, get rPage
  808.  
  809.              lda   ParamStart,s
  810.              sta   <RectPointer
  811.              lda   ParamStart+2,s
  812.              sta   <RectPointer+2       ; rectangle now set up for OpenPICTFile
  813.              bra   gotTheRect
  814.  
  815. getrPage     lda   #oprInfo+orPage
  816.              clc
  817.              adc   <PrRecPtr
  818.              sta   <RectPointer
  819.              lda   #0
  820.              adc   <PrRecPtr+2
  821.              sta   <RectPointer+2
  822.  
  823. gotTheRect   jsr   OpenPICTFile
  824.              bcs   OpenPageOut          ; error = no printing
  825.  
  826. ;
  827. ;  Now set the clipRgn and visRgn to a rectangular region the size of the
  828. ;  framing rectangle
  829. ;
  830.  
  831.              pha
  832.              pha
  833.              _NewRgn                    ; we got the region
  834.              pulllong <Temp             ; save it for a moment
  835.  
  836.              pei   <Temp+2
  837.              pei   <Temp                ; the region handle
  838.              pei   <RectPointer+2
  839.              pei   <RectPointer         ; the framing rectangle
  840.              _RectRgn                   ; now it's that size
  841.  
  842.              pei   <Temp+2
  843.              pei   <Temp
  844.              _SetClip                   ; copies this into the clipRgn
  845.  
  846.              pei   <Temp+2
  847.              pei   <Temp
  848.              _SetVisRgn                 ; copy it into the visRgn as well
  849.  
  850.              pei   <Temp+2
  851.              pei   <Temp
  852.              _DisposeRgn                ; throw away what we allocate
  853.  
  854. ;
  855. ;  That's basically it.  Now the application will draw into the printing
  856. ;  grafPort, which will go into our picture and we write it when we close
  857. ;  the page.  Nifty.
  858. ;
  859.  
  860. OpenPageOut  tax                        ; put the error code in X
  861.              lda   <temp2
  862.              ldy   #4
  863.              sta   [<PrRecHndl],y       ; restore the handle attributes
  864.  
  865.              ldy   #8
  866.              brl   EndOurWorld          ; and return to the real world
  867.  
  868.              END
  869.  
  870. **********************************************************************
  871. *
  872. * PrClosePage closes out the page.  For us, we write it out to disk
  873. * here.
  874. *
  875. *  Inputs:   Our stuff on direct page and a printing GrafPort
  876. *
  877. * Outputs:   None
  878. *
  879. **********************************************************************
  880.  
  881. PrClosePage  START
  882.              USING PicterData
  883.  
  884. ;
  885. ;  In this routine, it is very important that the direct page have
  886. ;  already been set up.  If it got set up on the entrance to this call,
  887. ;  some idiot unloaded the printer driver in the middle of the print
  888. ;  loop and all our stuff is invalid.
  889. ;
  890.  
  891.              bcc   Whew                 ; nothing's wrong yet
  892.              ldy   #4                   ; 4 bytes of parameters
  893.              ldx   #PrBozo              ; PrBozo error
  894.              brl   EndOurWorld
  895.  
  896. Whew         lda   <OurError
  897.              cmp   #PortNotOn           ; is this the error
  898.              bne   Whew2                ; still good
  899.              ldy   #4
  900.              ldx   #0                   ; don't return error, just return
  901.              brl   EndOurWorld
  902.  
  903. Whew2        anop
  904.  
  905. ;
  906. ;  Note that if we did support immediate mode, we'd want to do a form feed
  907. ;  here.
  908. ;
  909.  
  910.              lda   #PrClosePageMsg
  911.              sta   <ParamLongA
  912.              lda   #PrClosePageMsg|-16
  913.              sta   <ParamLongA+2
  914.              jsr   StatusMessage        ; PrClosePage message
  915.  
  916.              jsr   ClosePICTFile        ; close out our printing
  917.  
  918. ClosePageOut tax
  919.              ldy   #4
  920.              brl   EndOurWorld          ; that's all!
  921.  
  922.              END
  923.  
  924. **********************************************************************
  925. *
  926. * For any real printer driver, PrPicFile is the main course of the
  927. * printing meal.  This routine takes all the saved up images, spooled
  928. * either to memory or to disk and prints them.  This routine will be
  929. * pretty big for most drivers.
  930. *
  931. * Aha, but this isn't most drivers.  This is pretty small and does no
  932. * actual imaging.  See the article for more on PrPicFile.
  933. *
  934. *  Inputs:   PrintRecordHandle, printing GrafPort and statusRec
  935. *
  936. * Outputs:   None
  937. *
  938. **********************************************************************
  939.  
  940. PrPicFile    START
  941.              USING PicterData
  942.  
  943. ;
  944. ;  In this routine, it is very important that the direct page have
  945. ;  already been set up.  If it got set up on the entrance to this call,
  946. ;  some idiot unloaded the printer driver in the middle of the print
  947. ;  loop and all our stuff is invalid.
  948. ;
  949.  
  950.              bcc   Whew                 ; nothing's wrong yet
  951.              ldy   #12                  ; 12 bytes of parameters
  952.              ldx   #PrBozo              ; PrBozo error
  953.              brl   EndOurWorld
  954.  
  955. Whew         lda   <OurError
  956.              cmp   #PortNotOn           ; is this the error
  957.              bne   Whew2                ; still good
  958.              ldy   #12
  959.              ldx   #0                   ; don't return error, just return
  960.              brl   EndOurWorld
  961.  
  962. Whew2        anop
  963.  
  964.              jsr   StartStatusMessage
  965.  
  966.              lda   #PrPicFileMsg
  967.              sta   <ParamLongA
  968.              lda   #PrPicFileMsg|-16
  969.              sta   <ParamLongA+2
  970.              jsr   StatusMessage        ; "PrPicFile"
  971.  
  972.  
  973. ;
  974. ;  Even though we're not printing, we'll go through some of the motions
  975. ;  to make the system happy.  For example, we'll set up the statusRec and
  976. ;  call the idleProc procedure at least once just to make it happy (and to
  977. ;  demonstrate this stuff).
  978. ;
  979.  
  980.              lda   ParamStart+4,s
  981.              ora   ParamStart+6,s       ; is this NIL?
  982.              beq   GetGrafPort          ; yes, allocate a graf port
  983.              lda   ParamStart+4,s
  984.              sta   <PortPointer
  985.              lda   ParamStart+6,s
  986.              sta   <portPointer+2       ; put it on direct page
  987.              stz   <WeGotPort           ; initialize this to FALSE
  988.              bra   GotGrafPort
  989.  
  990. GetGrafPort  pha
  991.              pha                        ; space for result
  992.              pushlong #GrafPortSize
  993.              pei   <MyID
  994.              pushword #$C000            ; locked
  995.              lda   #0
  996.              pha
  997.              pha                        ; no location
  998.              _NewHandle
  999.              tax                        ; save error code
  1000.              pulllong <PortHandle
  1001.              stx   <OurError
  1002.              bcc   NoErrorHere
  1003.              txa                        ; put our error in A for PicFileOut
  1004.              brl   PicFileOut           ; no printing for us
  1005.  
  1006. NoErrorHere  ldy   #2
  1007.              lda   [PortHandle],y
  1008.              sta   <PortPointer+2
  1009.              lda   [PortHandle]
  1010.              sta   <PortPointer
  1011.  
  1012.              lda   #1
  1013.              sta   <WeGotPort
  1014.  
  1015. GotGrafPort  anop
  1016.  
  1017.              pei   <PortPointer+2
  1018.              pei   <PortPointer
  1019.              _OpenPort                  ; make it nice and grafPort-ical
  1020.  
  1021.              lda   ParamStart,s         ; checking the statusRecPtr
  1022.              ora   ParamStart+2,s       ; is it zero
  1023.              beq   NewStatusRec         ; yes, get a new one
  1024.              lda   ParamStart,s
  1025.              sta   <StatusRecPtr
  1026.              lda   ParamStart+2,s
  1027.              sta   <StatusRecPtr+2
  1028.              stz   <StatusRecHandle
  1029.              stz   <StatusRecHandle+2   ; know that we didn't use this
  1030.              bra   GotStatusRec
  1031.  
  1032. NewStatusRec pha
  1033.              pha                        ; space for result
  1034.              pushlong #StatusRecSize    ; size
  1035.              pei   <MyID                ; owner ID
  1036.              pushword #$C000            ; locked and fixed
  1037.              lda   #0
  1038.              pha
  1039.              pha                        ; no location
  1040.              _NewHandle
  1041.              tax
  1042.              pulllong <StatusRecHandle
  1043.              txa
  1044.              bcc   DerefSRHandle
  1045.              brl   PicFileOut           ; get out of here
  1046.  
  1047. DerefSRHandle lda   [<StatusRecHandle]
  1048.              sta   <StatusRecPtr
  1049.              ldy   #2
  1050.              lda   [<StatusRecHandle],y
  1051.              sta   <StatusRecPtr+2
  1052.  
  1053.              pushlong #MyStatusRec      ; our default copy
  1054.              pei   <StatusRecPtr+2
  1055.              pei   <StatusRecPtr        ; our destination
  1056.              pushlong #StatusRecSize
  1057.              _BlockMove                 ; move it there
  1058.  
  1059. GotStatusRec ldy   #ohPrint
  1060.              lda   <PrRecHndl
  1061.              sta   [<StatusRecPtr],y
  1062.              iny
  1063.              iny
  1064.              lda   <PrRecHndl+2
  1065.              sta   [<StatusRecPtr],y
  1066.  
  1067.              iny
  1068.              iny
  1069.              lda   <PortPointer
  1070.              sta   [<StatusRecPtr],y
  1071.              iny
  1072.              iny
  1073.              lda   <PortPointer+2
  1074.              sta   [<StatusRecPtr],y
  1075.  
  1076.              ldy   #2
  1077.              lda   [PrRecHndl],y
  1078.              sta   <PrRecPtr+2
  1079.              lda   [PrRecHndl]
  1080.              sta   <PrRecPtr            ; dereference the print record handle
  1081.  
  1082.              jsr   doIdleProc           ; make it happy
  1083.  
  1084. ;
  1085. ;  Here's where the real stuff goes - we just don't have any
  1086. ;
  1087.  
  1088.              pei   <PortPointer+2
  1089.              pei   <PortPointer
  1090.              _ClosePort
  1091.  
  1092.              lda   <WeGotPort
  1093.              beq   PortGone
  1094.  
  1095.              pei   <PortHandle+2
  1096.              pei   <PortHandle
  1097.              _DisposeHandle
  1098.  
  1099. PortGone     lda   <StatusRecHandle
  1100.              ora   <StatusRecHandle+2
  1101.              beq   StatusRecGone
  1102.  
  1103.              pei   <StatusRecHandle+2
  1104.              pei   <StatusRecHandle
  1105.              _DisposeHandle
  1106.  
  1107. StatusRecGone anop
  1108.  
  1109.              jsr   FinishStatusMessage
  1110.  
  1111.              pei   <OldCursor+2
  1112.              pei   <OldCursor
  1113.              _SetCursor
  1114.              bcs   PicFileOut
  1115.  
  1116.              lda   #0                   ; no errors!  yay!
  1117.  
  1118. PicFileOut   tax                        ; error in X
  1119.              ldy   #12                  ; twelve bytes of parameters
  1120.              brl   EndOurWorld
  1121.  
  1122.              END
  1123.  
  1124. **********************************************************************
  1125. *
  1126. * PrError returns the last driver error we have.
  1127. *
  1128. *  Inputs:   Space for result
  1129. *
  1130. * Outputs:   Error word on stack
  1131. *
  1132. **********************************************************************
  1133.  
  1134. PrError      START
  1135.  
  1136.              ldy   #0
  1137.              jsr   CheckTheWorld
  1138.  
  1139.              lda   <OurError            ; and here it is
  1140.              sta   ParamStart,s         ; and there it goes
  1141.              ldy   #0
  1142.              ldx   #$FFFF
  1143.              brl   EndOurWorld
  1144.  
  1145.              END
  1146.  
  1147. **********************************************************************
  1148. *
  1149. *  PrSetError sets our internal error variable to the parameter.
  1150. *
  1151. *  Inputs:   Error word on the stack
  1152. *
  1153. * Outputs:   None
  1154. *
  1155. **********************************************************************
  1156.  
  1157. PrSetError   START
  1158.  
  1159.              ldy   #2
  1160.              jsr   CheckTheWorld
  1161.  
  1162.              lda   ParamStart,s         ; get the error
  1163.              sta   <OurError
  1164.              ldx   #$FFFF               ; don't change the error status
  1165.              ldy   #2
  1166.              brl   EndOurWorld
  1167.  
  1168.              END
  1169.  
  1170. **********************************************************************
  1171. *
  1172. * GetDeviceName (also known as PrChanged) is called when drivers are
  1173. * changed.  Although we don't have anything to do here, we'll give
  1174. * a sample of what we would do if we could run on a network.
  1175. *
  1176. *  Inputs:   None
  1177. *
  1178. * Outputs:   None
  1179. *
  1180. **********************************************************************
  1181.  
  1182. GetDeviceName START
  1183.  
  1184.              ldy   #0
  1185.              jsr   CheckTheWorld
  1186.  
  1187.              pushlong #DeviceNameStr
  1188.              ldx   #$1913
  1189.              jsl   $E10000              ; _PrDevPrChanged
  1190.  
  1191.              ldy   #0                   ; no bytes to return
  1192.  
  1193.              ldx   #0                   ; no error
  1194.              brl   EndOurWorld
  1195.  
  1196. DeviceNameStr str  '='                  ; in AppleTalk NBP format
  1197.              str   'Picter'
  1198.              str   '*'
  1199.  
  1200.              END
  1201.  
  1202. **********************************************************************
  1203. *
  1204. * PrDriverVer returns the version word for this driver.
  1205. *
  1206. *  Inputs:   Space for result
  1207. *
  1208. * Outputs:   Version of this driver
  1209. *
  1210. **********************************************************************
  1211.  
  1212. PrDriverVer  START
  1213.  
  1214.              ldy   #0
  1215.              jsr   CheckTheWorld
  1216.  
  1217.              lda   #OurVersion
  1218.              sta   ParamStart,s         ; the space on the stack
  1219.              ldy   #0                   ; no bytes to remove
  1220.              ldx   #0                   ; no errors
  1221.              brl   EndOurWorld
  1222.  
  1223.              END
  1224.  
  1225. **********************************************************************
  1226. *
  1227. * PrGetPrinterSpecs returns characteristics of the printer.
  1228. *
  1229. *  Inputs:   Two word spaces
  1230. *
  1231. * Outputs:   Printer type and characteristics
  1232. *
  1233. **********************************************************************
  1234.  
  1235. PrGetPrinterSpecs  START
  1236.  
  1237.              ldy   #0
  1238.              jsr   CheckTheWorld
  1239.  
  1240.              lda   #OuriDev
  1241.              sta   ParamStart+2,s
  1242.  
  1243.              lda   #OurCharcs
  1244.              sta   ParamStart,s
  1245.  
  1246.              ldy   #0                   ; no bytes to remove
  1247.              ldx   #0                   ; no errors
  1248.              brl   EndOurWorld
  1249.  
  1250.              END
  1251.  
  1252. **********************************************************************
  1253. *
  1254. * PrGetPgOrientation returns the page orientation from a print
  1255. * record for our driver.
  1256. *
  1257. *  Inputs:   Word Space for result
  1258. *            Print record handle
  1259. *
  1260. * Outputs:   Page orientation (0 = portrait, 1 = landscape)
  1261. *
  1262. **********************************************************************
  1263.  
  1264. PrGetPgOrientation  START
  1265.  
  1266.              ldy   #4
  1267.              jsr   CheckTheWorld
  1268.  
  1269.              lda   ParamStart,s
  1270.              sta   <Temp
  1271.              lda   ParamStart+2,s
  1272.              sta   <Temp+2              ; temp = print record handle
  1273.  
  1274.              lda   [<Temp]
  1275.              sta   <Temp2
  1276.              ldy   #2
  1277.              lda   [<Temp],y
  1278.              sta   <Temp2+2             ; temp2 = print record pointer
  1279.  
  1280. ;
  1281. ;  We do this into Temp in case some bozo calls this in the middle of the
  1282. ;  printing loop, where our print record fields are filled
  1283. ;
  1284.  
  1285.              ldy   #oprStl+owDev
  1286.              lda   [<Temp2],y           ; the wDev field
  1287.              and   #$0002               ; clear all but bit 2
  1288.              bne   DoLandscape
  1289.  
  1290. DoPortrait   lda   #Portrait
  1291.              bra   OrientOut
  1292.  
  1293. DoLandscape  lda   #Landscape
  1294.  
  1295. OrientOut    sta   ParamStart+4,s
  1296.              ldx   #0                   ; no errors
  1297.              ldy   #4                   ; four bytes to remove
  1298.              brl   EndOurWorld
  1299.  
  1300.              END
  1301.  
  1302.  
  1303. **********************************************************************
  1304. *
  1305. * PrReserved (formerly PrControl) is treated as if there are no
  1306. * parameters, even though PrControl had some, so don't even THINK
  1307. * about making this call.
  1308. *
  1309. *  Inputs:   None
  1310. *
  1311. * Outputs:   None
  1312. *
  1313. **********************************************************************
  1314.  
  1315. PrReserved   START
  1316.  
  1317.              ldx   #$0002               ; as in Tool Locator function not found
  1318.              ldy   #0
  1319.              brl   EndOurWorld
  1320.  
  1321.              END
  1322.  
  1323. **********************************************************************
  1324. *
  1325. *  MakeOurWorld sets up a private direct page and sets the data bank
  1326. *  register to our code bank.  We check our internal storage to see
  1327. *  if our direct page already exists, and if not, we create it.
  1328. *
  1329. *  Inputs:   None.  Assumes no bytes between the two RTL addresses and
  1330. *            the RTS address for this routine.
  1331. *
  1332. * Outputs:   Direct page and data bank registers on stack.  The
  1333. *            carry is set if our DP did not exist on entry.  Preserves
  1334. *            the X register.
  1335. *
  1336. **********************************************************************
  1337.  
  1338. ;
  1339. ;  When this routine is finished, the stack looks like this:
  1340. ;
  1341. ;  | Previous contents |
  1342. ;  +-------------------+
  1343. ;  | Parameters (10,s) |
  1344. ;  +-------------------+
  1345. ;  | RTL2        (7,s) |
  1346. ;  +-------------------+
  1347. ;  | RTL1        (4,s) |
  1348. ;  +-------------------+
  1349. ;  | Old DP reg  (2,s) |
  1350. ;  +-------------------+
  1351. ;  | Old DBR     (1,s) |
  1352. ;  +-------------------+
  1353. ;  |                   |  <-- SP
  1354. ;
  1355. ;  We've already equated ParamStart to 10 for this reason.  If you want to
  1356. ;  allocate DP space on the stack, change ParamStart accordingly.
  1357. ;
  1358. ;  NOTE:  THIS ROUTINE MUST SUPPORT DRIVER REENTRANCY!  When we make any
  1359. ;  Port Driver or other Tool Locator calls, someone could call one of our
  1360. ;  routines in the middle of one of our routines (GetDeviceName is the
  1361. ;  most likely candidate).  This MUST be reentrant.
  1362. ;
  1363.  
  1364. MakeOurWorld START
  1365.              USING PicterData
  1366.  
  1367.              pla                        ; the RTS address
  1368.              phd                        ; save the old DP
  1369.              phb                        ; save the old DBR
  1370.              pha                        ; put the RTS address back
  1371.  
  1372.              phk
  1373.              plb                        ; now we can use 16-bit addressing
  1374.  
  1375. ;
  1376. ;  We look at our internal variable OurDP to see if it's NIL.  We assemble
  1377. ;  it to zero so it will be that way when it's loaded.  When we allocate our
  1378. ;  direct page, we change it to that value.  When the Print Manager unloads
  1379. ;  our driver, our DP will go away because we allocate it with our user ID.
  1380. ;  When it gets reloaded, OurDP will be zero again.
  1381. ;  Therefore, if OurDP is zero we don't have a direct page yet.
  1382. ;
  1383.              lda   OurDP
  1384.              bne   GotDP                ; we've got it
  1385.  
  1386. NoDP         phx                        ; save the X register
  1387.              pha                        ; space for result
  1388.              _MMStartUp                 ; leave our ID on the stack
  1389.              lda   1,s                  ; but get a copy
  1390.  
  1391.              pha
  1392.              pha                        ; space for result
  1393.  
  1394.              pea   $0000
  1395.              pea   $0100                ; pushlong #$100 without destroying A
  1396.              pha                        ; our user ID
  1397.              pea   $C015                ; locked, fixed, no bank cross, page
  1398. *                                       ; aligned and fixed bank
  1399.              lda   #0
  1400.              pha
  1401.              pha                        ; location in bank zero
  1402.              _NewHandle
  1403.              bcc   GotHandle
  1404.  
  1405. ;
  1406. ;  If we can't get our DP, we return with the error in A and the carry set.
  1407. ;
  1408.              tay                        ; save the error code
  1409.              pla
  1410.              pla                        ; get rid of the NIL handle
  1411.              pla                        ; pop our user ID
  1412.              plx                        ; pop the saved X register
  1413.              tya
  1414.              cmp #1
  1415.              rts                        ; and back out
  1416.  
  1417. GotHandle    tsc                        ; put the stack pointer
  1418.              tcd                        ; into the direct page
  1419.              lda   [1]                  ; the handle on DP
  1420.              sta   OurDP
  1421.              tcd                        ; and set our direct page from it
  1422.              pla
  1423.              pla                        ; we don't need the handle
  1424.  
  1425.              pla                        ; our User ID
  1426.              sta   <MyID                ; save it on DP
  1427.  
  1428.              plx                        ; the saved X register
  1429.  
  1430.              lda   #0
  1431.              sec                        ; we had to create the DP
  1432.              rts
  1433.  
  1434. GotDP        tcd
  1435.              lda   #0
  1436.              clc
  1437.              rts                        ; we already had the DP
  1438.  
  1439.              END
  1440.  
  1441. **********************************************************************
  1442. *
  1443. * CheckTheWorld looks at the output of MakeOurWorld and sees if
  1444. * something is really wrong.  If it is, it branches to EndOurWorld
  1445. * for us.  If not, it returns to the caller.
  1446. *
  1447. * This is for the use of those calls which don't need to know whether
  1448. * or not our direct page already existed.  If they do, they need to
  1449. * check individually and not rely on this routine.
  1450. *
  1451. *  Inputs:   Parameters to remove (in bytes) in Y
  1452. *            Takes Accumulator and carry flag values from MakeOurWorld
  1453. *
  1454. * Outputs:   Either returns or goes to EndOurWorld
  1455. *
  1456. **********************************************************************
  1457.  
  1458. CheckTheWorld  START
  1459.  
  1460.              bcc   WorldOK
  1461.              pha
  1462.              pla
  1463.              beq   WorldOK              ; only if carry is set
  1464.  
  1465.              tax                        ; put error code in X
  1466.              pla                        ; pop the RTS address
  1467.              bra   EndOurWorld          ; and get out of here
  1468.  
  1469. WorldOK      rts
  1470.  
  1471.              END
  1472.  
  1473. **********************************************************************
  1474. *
  1475. *  EndOurWorld isn't really pessimistic.  It restores the direct page
  1476. *  to the value MakeOurWorld pushed on the stack.  It removes the number
  1477. *  of bytes above the two RTL addresses specified in the Y register
  1478. *  and conditions the carry based on an error code passed in X.
  1479. *
  1480. *  Inputs:  Direct page on the stack, number of parameters to remove in
  1481. *           Y and an error code in X
  1482. *
  1483. * Outputs:  Removes Y parameters and RTLs with the carry conditioned and
  1484. *           the error code in the accumulator.
  1485. *
  1486. **********************************************************************
  1487.  
  1488. EndOurWorld  START
  1489.  
  1490.              cpx   #$FFFF               ; should we change the error?
  1491.              beq   NoErrorChange
  1492.  
  1493.              stx   <OurError            ; for PrError's future use
  1494.              dex
  1495.  
  1496. NoErrorChange inx                       ; This was Dave's idea.  Sheesh.
  1497.  
  1498. ;
  1499. ;  For $FFFF the dex is skipped, leaving X as zero
  1500. ;
  1501.  
  1502.              plb                        ; reset the old DBR
  1503.              pld                        ; reset the old DP
  1504.  
  1505.              phy                        ; save the # of parameters to remove
  1506.              tsc                        ; take the stack with Y into A
  1507.              clc
  1508.              adc   1,s                  ; add the # of parameters to the SP
  1509.              tay                        ; and save as an index
  1510.  
  1511.              tsc                        ; another copy of the SP
  1512.              phx                        ; save the error code
  1513.              tax                        ; and index into the stack as well
  1514.  
  1515.              phb                        ; save the DBR so we can
  1516.              pea   0
  1517.              plb
  1518.              plb                        ; set it to zero for 16-bit addressing
  1519.  
  1520. ;
  1521. ;  With X equal to the stack pointer and Y equal to the stack pointer plus
  1522. ;  the number of parameters to remove and B in bank zero, we can use addressing
  1523. ;  like 3,x and 3,y to simulate stack addressing using X and Y as two different
  1524. ;  stack pointers.  The toolbox does this and it's pretty nifty.
  1525. ;
  1526.              lda   |7,x
  1527.              sta   |7,y                 ; moved two bytes
  1528.              lda   |5,x
  1529.              sta   |5,y                 ; moved four bytes
  1530.              lda   |3,x
  1531.              sta   |3,y                 ; moved all six bytes of RTL addresses
  1532.  
  1533.              plb                        ; restore the DBR
  1534.              plx                        ; restore the error code
  1535.  
  1536.              tsc                        ; yet another stack pointer copy
  1537.              clc
  1538.              adc   1,s                  ; add the # of parameters
  1539.              adc   #2                   ; and don't forget the pcount!
  1540.              tcs                        ; now the stack is moved
  1541.  
  1542. RealGone     txa
  1543.              cmp #1                     ; condition the carry
  1544.              rtl
  1545.  
  1546.              END
  1547.  
  1548. **********************************************************************
  1549. *
  1550. * OpenPICTFile increments the last letter of the supplied pathname
  1551. * until it finds one that doesn't exist or gets some other GS/OS error.
  1552. * It then opens the file and stores the ref num on direct page.  It
  1553. * then opens a QD II Picture for the current port and puts the picture
  1554. * handle on direct page.
  1555. *
  1556. *  Inputs:   RectPointer on DP for the Picture's frameRect
  1557. *
  1558. * Outputs:   PictHandle and FileRefNum on direct page
  1559. *
  1560. **********************************************************************
  1561.  
  1562. OpenPICTFile START
  1563.              USING PicterData
  1564.  
  1565.              stz   <PictHandle+2
  1566.              stz   <PictHandle
  1567.              stz   <RefNum
  1568.  
  1569. GFILoop      _GetFileInfoGS GFIParams   ; does it exist?
  1570.              bcc   FileExists
  1571.              cmp   #$0046               ; file not found?
  1572.              beq   GotFileName
  1573.              brl   ExitOpen             ; get out of this routine
  1574.  
  1575. FileExists   shortm                     ; 8-bit land
  1576.              inc   FileNameSuffix
  1577.              longm
  1578.              bra   GFILoop
  1579.  
  1580. GotFileName  _CreateGS CreateParams
  1581.              bcs   ExitOpen
  1582.  
  1583.              _OpenGS OpenParams
  1584.              bcs   ExitOpen
  1585.              lda   OpenRefNum
  1586.              sta   <RefNum
  1587.  
  1588. DoPicture    pha
  1589.              pha                        ; space for result
  1590.  
  1591.              pei   <RectPointer+2
  1592.              pei   <RectPointer
  1593.              _OpenPicture
  1594.              tax
  1595.              pulllong <PictHandle
  1596.              txa
  1597.  
  1598. ExitOpen     rts                        ; carry's still properly set
  1599.  
  1600.              END
  1601.  
  1602. **********************************************************************
  1603. *
  1604. * ClosePICTFile writes the data in RefNum on direct page to the
  1605. * file opened with RefNum, closes the file and kills the picture.
  1606. *
  1607. *  Inputs:   PictHandle and RefNum on direct page
  1608. *
  1609. * Outputs:   None
  1610. *
  1611. **********************************************************************
  1612.  
  1613. ClosePICTFile      START
  1614.              USING PicterData
  1615.  
  1616.              lda   <PictHandle+1
  1617.              beq   NoPict
  1618.              _ClosePicture              ; first things first
  1619.  
  1620. NoPict       lda   <RefNum
  1621.              beq   NoFile
  1622.              sta   WriteRefNum
  1623.              sta   CloseRefNum
  1624.  
  1625.              pha
  1626.              pha                        ; space for result
  1627.              pei   <PictHandle+2
  1628.              pei   <PictHandle
  1629.              _GetHandleSize
  1630.              pulllong WriteReqCount     ; how much to write
  1631.  
  1632.              ldy   #4
  1633.              lda   [<PictHandle],y
  1634.              pha                        ; save handle attribs and lock
  1635.              ora   #$8000
  1636.              sta   [<PictHandle],y
  1637.              dey
  1638.              dey
  1639.              lda   [<PictHandle],y
  1640.              sta   WriteBuffer+2
  1641.              lda   [<PictHandle]
  1642.              sta   WriteBuffer          ; pointer to the picture
  1643.              _WriteGS WriteParams
  1644.  
  1645.              tax
  1646.              pla
  1647.              ldy   #4
  1648.              sta   [<PictHandle],y
  1649.              phx
  1650.  
  1651.              _CloseGS CloseParams
  1652.              ply                        ; the error from Write, if any
  1653.              tax
  1654.              bcs   ExitClose
  1655.  
  1656.              tyx
  1657.              cpx   #1
  1658.              bcs   ExitClose            ; handle write errors, if any
  1659.  
  1660. NoFile       lda   <PictHandle+1
  1661.              beq   StillNoPict
  1662.              pei   <PictHandle+2
  1663.              pei   <PictHandle
  1664.              _KillPicture
  1665.  
  1666. StillNoPict  ldx   #0
  1667.  
  1668. ExitClose    txa
  1669.              cmp   #1
  1670.              rts
  1671.  
  1672.              END
  1673.  
  1674. **********************************************************************
  1675. *
  1676. * DoIdleProc calls the pIdleProc procedure if it is not nil.
  1677. *
  1678. *  Inputs:   PrRecPtr on direct page
  1679. *
  1680. * Outputs:   None
  1681. *
  1682. **********************************************************************
  1683.  
  1684. DoIdleProc   START
  1685.  
  1686.              ldy   #opIdleProc+2
  1687.              lda   [<PrRecPtr],y
  1688.              dey
  1689.              dey
  1690.              ora   [<PrRecPtr],y
  1691.              beq   ExitIdleLoop         ; nothing to call
  1692.  
  1693.              lda   [<PrRecPtr],y        ; low and middle bytes of pointer
  1694.              sta   IdleJSL+1
  1695.              iny
  1696.              lda   [<PrRecPtr],y
  1697.              sta   IdleJSL+2            ; middle and high bytes of pointer
  1698.  
  1699. IdleJSL      jsl   IdleJSL              ; self-modified (ack)
  1700.  
  1701. ExitIdleLoop rts
  1702.  
  1703.              END
  1704.  
  1705. *****************************************************************
  1706. *
  1707. *  Ben's dialog routines call a lot of subroutines to set and
  1708. *  retrieve items in the print record.  Rather than modify the
  1709. *  dialog routines to be more specific, we include these subroutines
  1710. *  in this segment.  Each of them assumes <PrRecPtr points to the
  1711. *  print record in question.  The "set" routines take the parameter
  1712. *  in the registers (as described for each routine) and the "get"
  1713. *  routines return parameters similarly.
  1714. *
  1715. *  These routines must be modified for your printer driver to return
  1716. *  the appopriate values.  These values are right for $8001 drivers,
  1717. *  which interpret the style subrecord as documented for the ImageWriter
  1718. *  driver in Toolbox Reference, Volume 1.
  1719. *
  1720. ******************************************************************
  1721.  
  1722. Metrics      START
  1723.              USING PicterData
  1724.  
  1725. ; GetPaper returns the paper type in A.
  1726.  
  1727. GetPaper     ENTRY
  1728.              ldy   #oprStl+opaperType
  1729.              lda   [<PrRecPtr],y
  1730.              rts
  1731.  
  1732. ; SetPaper takes the paper type in OptionA (not like GetPaper)
  1733.  
  1734. SetPaper     ENTRY
  1735.              ldy   #oprStl+opaperType
  1736.              lda   <OptionA
  1737.              sta   [<PrRecPtr],y
  1738.              rts
  1739.  
  1740. ; GetReduction returns the reduction (100/50 = 0/1) in A.
  1741.  
  1742. GetReduction ENTRY
  1743.              ldy   #oprStl+owDev
  1744.              lda   [<PrRecPtr],y
  1745.              and   #%0000000000001000   ; reduction bit in wDev
  1746.              bne   ReductionIs100       ; in the print record, the bit clear
  1747. Reductionis50 lda #1                    ; means 50% reduction, which is reverse
  1748.              bra   GetReducOut          ; of how we want it
  1749. Reductionis100 lda #0
  1750. GetReducOut  rts
  1751.  
  1752. ; SetReduction takes a value in OptionA and sets page reduction to 50% if
  1753. ; OptionA is 1 and to 100% if OptionA is 0.
  1754.  
  1755. SetReduction ENTRY
  1756.              lda   <OptionA
  1757.              asl   a
  1758.              asl   a
  1759.              asl   a                    ; the bit is now in bit 3
  1760.              eor   #wDevReduction       ; flip the bit
  1761.              ldy   #oprStl+owDev
  1762.              pha
  1763.              lda   [<PrRecPtr],y
  1764.              and   #$FFF7               ; clear out our bit
  1765.              ora   1,s                  ; set it appopriately
  1766.              sta   [<PrRecPtr],y
  1767.              pla
  1768.              jsr   CalcMetrics          ; fix up the paper sizes
  1769.              rts
  1770.  
  1771. ; GetPageGap gets page gap (yes/no) in the zero flag:  BEQ succeds if there
  1772. ; is a normal page gap and BNE succeeds if not
  1773.  
  1774. GetPageGap   ENTRY
  1775.              ldy   #oprStl+owDev
  1776.              lda   [<PrRecPtr],y
  1777.              and   #wDevGap
  1778.              eor   #wDevGap             ; flip the bit
  1779.              rts
  1780.  
  1781. ; SetPageGap takes a word in OptionA - zero for regular gap and non-zero
  1782. ; for no gap
  1783.  
  1784. SetPageGap   ENTRY
  1785.              ldy   #oprStl+owDev
  1786.              lda   [<PrRecPtr],y
  1787.              ldx   <OptionA             ; the value to use
  1788.              bne   SetNoGap             ; non-zero = no gap
  1789. SetGap       ora   #wDevGap             ; set the bit
  1790.              bra   StoreGap
  1791. SetNoGap     and   #$FFFF-wDevGap       ; set the bit
  1792. StoreGap     sta   [<PrRecPtr],y
  1793.              jsr   CalcMetrics          ; fix things up
  1794.              rts
  1795.  
  1796. ; GetVSize returns vertical size in the zero flag (BEQ taken if normal size)
  1797.  
  1798. GetVSize     ENTRY
  1799.  
  1800.              ldy   #oprStl+owDev
  1801.              lda   [<PrRecPtr],y
  1802.              and   #wDevVSize
  1803.              eor   #wDevVSize
  1804.              rts
  1805.  
  1806. ; SetVSize takes 0 for normal and non-zero for condensed in OptionA and sets
  1807. ; the print record accordingly
  1808.  
  1809. SetVSize     ENTRY
  1810.              ldy   #oprStl+owDev
  1811.              lda   [<PrRecPtr],y
  1812.              ldx   <OptionA             ; the value to use
  1813.              bne   SetCondensed         ; non-zero = no gap
  1814. SetNormal    ora   #wDevVSize           ; set the bit
  1815.              bra   StoreVSize
  1816. SetCondensed and   #$FFFF-wDevVSize     ; set the bit
  1817. StoreVSize   sta   [<PrRecPtr],y
  1818.              jsr   CalcMetrics          ; fix things up
  1819.              rts
  1820.  
  1821. ; GetOrientation returns 1 in A for landscape, zero for portrait
  1822.  
  1823. GetOrientation ENTRY
  1824.              ldy   #oprStl+owDev
  1825.              lda   [<PrRecPtr],y
  1826.              and   #wDevOrientation
  1827.              eor   #wDevOrientation
  1828.              beq   GetOrientOut
  1829.              lda   #1
  1830. GetOrientOut rts
  1831.  
  1832. ; SetOrientation takes 0 in OptionA for portrait or non-zero for landscape
  1833.  
  1834. SetOrientation ENTRY
  1835.  
  1836.              ldy   #oprStl+owDev
  1837.              lda   [<PrRecPtr],y
  1838.              ldx   <OptionA             ; the value to use
  1839.              bne   SetLand              ; non-zero = landscape
  1840. SetPortrait  ora   #wDevOrientation     ; set the bit
  1841.              bra   StoreOrient
  1842. SetLand      and   #$FFFF-wDevOrientation ; set the bit
  1843. StoreOrient  sta   [<PrRecPtr],y
  1844.              jsr   CalcMetrics          ; fix things up
  1845.              rts
  1846.  
  1847. ; GetQuality returns the quality in A: 0 for standard, 1 for better
  1848.  
  1849. GetQuality   ENTRY
  1850.  
  1851.              ldy   #oprStl+owDev
  1852.              lda   [<PrRecPtr],y
  1853.              and   #wDevBetterText
  1854.              beq   GetQualOut           ; if zero, we're done
  1855.              lda   #1
  1856. GetQualOut   rts
  1857.  
  1858. ; SetQuality takes 0 for standard or 1 for better in OptionA and sets
  1859. ; the print record accordingly
  1860.  
  1861. SetQuality   ENTRY
  1862.              ldy   #oPrStl+owDev
  1863.              lda   [<PrRecPtr],y
  1864.              and   #$FFFF-wDevBetterText ; clear out bit zero
  1865.              ora   <OptionA             ; set it if necessary
  1866.              sta   [<PrRecPtr],y
  1867.  
  1868. ;
  1869. ; This driver doesn't support both draft and spool printing, but if it did,
  1870. ; or if you do, this is where to set the parameter in the job subrecord.  If
  1871. ; you know it's draft printing, assuming you use zero for draft printing,
  1872. ; then you can do this:
  1873. ;
  1874. ;            shortm
  1875. ;            lda   #0                   ; draft printing
  1876. ;            ldy   #oprJob+oBJDocLoop   ; the BJDocLoop byte
  1877. ;            sta   [<PrRecPtr],y
  1878. ;            longm
  1879. ;            stz   <OptionA
  1880. ;            jsr   SetReduction         ; zero in OptionA = 100%
  1881. ;            jsr   SetPageGap           ; zero in OptionA = default gap
  1882. ;            jsr   SetOrientation       ; zero in OptioNA = portrait
  1883. ;
  1884.  
  1885.              rts
  1886.  
  1887. ; GetColor returns the color in the zero flag = BEQ if no color, BNE if color
  1888.  
  1889. GetColor     ENTRY
  1890.              ldy   #oprStl+owDev
  1891.              lda   [<PrRecPtr],y
  1892.              and   #wDevColor
  1893.              rts
  1894.  
  1895. ; SetColor takes zero in OptionA for B/W and non-zero for color
  1896.  
  1897. SetColor     ENTRY
  1898.              ldy   #oprStl+owDev
  1899.              lda   [<PrRecPtr],y
  1900.              ldx   <OptionA
  1901.              beq   SetBW                ; black and white
  1902. SetRainbow   ora   #wDevColor
  1903.              bra   StoreColor
  1904. SetBW        and   #$FFFF-wDevColor
  1905. StoreColor   sta   [<PrRecPtr],y
  1906.              rts
  1907.  
  1908. ; GetFeed gets manual page option in zero flag (BEQ works if manual feed)
  1909.  
  1910. GetFeed      ENTRY
  1911.              ldy   #oprStl+oFeed
  1912.              lda   [<PrRecPtr],y
  1913.              rts
  1914.  
  1915. ; SetFeed sets the manual page option (0 = manual feed)
  1916.  
  1917. SetFeed      ENTRY
  1918.              ldy   #oprStl+oFeed
  1919.              lda   <OptionA
  1920.              sta   [<PrRecPtr],y
  1921.              jsr   CalcMetrics
  1922.              rts
  1923.  
  1924. ; SetPageRange takes the first page in OptionA and the last page in OptionB
  1925.  
  1926. SetPageRange ENTRY
  1927.              ldy   #oprJob+oiFstPage
  1928.              lda   <OptionA
  1929.              sta   [<PrRecPtr],y
  1930.              ldy   #oprJob+oiLstPage
  1931.              lda   <OptionB
  1932.              sta   [<PrRecPtr],y
  1933.              jsr   CalcMetrics
  1934.              rts
  1935.  
  1936. ; SetCopies sets the number of copies from OptionA
  1937.  
  1938. SetCopies    ENTRY
  1939.              ldy   #oprJob+oiCopies
  1940.              lda   <OptionA
  1941.              sta   [<PrRecPtr],y
  1942.              jsr   CalcMetrics
  1943.              rts
  1944.  
  1945. ; CalcMetrics makes sure the resolutions, width, rPage and rPaper are right
  1946. ; for the values in the print record
  1947.  
  1948. CalcMetrics  ENTRY
  1949.  
  1950. ; we don't use landscape or lots of paper types - all we do is look at the
  1951. ; paper type and make sure the page and paper rectangles are correct
  1952.  
  1953. ;
  1954. ;  We have four possibilities for rectangles - screen 320, screen 640 and
  1955. ;  US letter 320 and US letter 640.  First we check to be sure that the
  1956. ;  paper type is either US letter or screen sized, and then blast in the
  1957. ;  appropriate page and paper rectangles (easier than comparing them)
  1958. ;
  1959.  
  1960.              ldy   #oprStl+opaperType
  1961.              lda   [PrRecPtr],y
  1962.              cmp   #paperTypeUSALetter
  1963.              bne   KeepChecking
  1964.              brl   RectLetter
  1965. KeepChecking cmp   #4
  1966.              bne   BadRects
  1967.              brl   RectScreen
  1968. BadRects     lda   #$FFFF               ; flag to do a default
  1969.              sta   <RectChanged
  1970.              brl   DoneRects            ; get out of here
  1971.  
  1972. RectLetter   pha
  1973.              _GetMasterSCB
  1974.              pla
  1975.              sta   <MasterSCB
  1976.              and   #$0080
  1977.              beq   RectLetter320
  1978.  
  1979. RectLetter640 ldy  #oprInfo+orPage
  1980. RectLoop1    lda   [PrRecPtr],y
  1981.              cmp   FPrPage640-orPage-oprInfo,y
  1982.              beq   OK1
  1983.  
  1984.              pushlong #FPrPage640
  1985.              lda   <PrRecPtr
  1986.              clc
  1987.              adc   #oprInfo+orPage
  1988.              tax
  1989.              lda   <PrRecPtr+2
  1990.              adc   #0
  1991.              pha
  1992.              phx                        ; pointer to destination
  1993.              pushlong #16               ; two rects = 16 bytes
  1994.              _BlockMove
  1995.              inc   <RectChanged
  1996.              brl   DoneRects
  1997.  
  1998. OK1          iny
  1999.              iny
  2000.              cpy   #oprInfo+orPage+16
  2001.              bne   RectLoop1
  2002.              brl   DoneRects
  2003.  
  2004. RectLetter320 ldy #oprInfo+orPage
  2005. RectLoop2    lda   [PrRecPtr],y
  2006.              cmp   FPrPage320-orPage-oprInfo,y
  2007.              beq   OK2
  2008.  
  2009.              pushlong #FPrPage320
  2010.              lda   <PrRecPtr
  2011.              clc
  2012.              adc   #oprInfo+orPage
  2013.              tax
  2014.              lda   <PrRecPtr+2
  2015.              adc   #0
  2016.              pha
  2017.              phx                        ; pointer to destination
  2018.              pushlong #16               ; two rects = 16 bytes
  2019.              _BlockMove
  2020.              inc   <RectChanged
  2021.              brl   DoneRects
  2022.  
  2023. OK2          iny
  2024.              iny
  2025.              cpy   #oprInfo+orPage+16
  2026.              bne   RectLoop2
  2027.              brl   DoneRects
  2028.  
  2029. RectScreen   lda   <MasterSCB
  2030.              and   #$0080
  2031.              beq   RectScreen320
  2032.  
  2033. RectScreen640 ldy  #oprInfo+orPage
  2034. RectLoop3    lda   [PrRecPtr],y
  2035.              cmp   SCrPage640-orPage-oprInfo,y
  2036.              beq   OK3
  2037.  
  2038.              pushlong #SCrPage640
  2039.              lda   <PrRecPtr
  2040.              clc
  2041.              adc   #oprInfo+orPage
  2042.              tax
  2043.              lda   <PrRecPtr+2
  2044.              adc   #0
  2045.              pha
  2046.              phx                        ; pointer to destination
  2047.              pushlong #16               ; two rects = 16 bytes
  2048.              _BlockMove
  2049.              inc   <RectChanged
  2050.              brl   DoneRects
  2051.  
  2052. OK3          iny
  2053.              iny
  2054.              cpy   #oprInfo+orPage+16
  2055.              bne   RectLoop3
  2056.              brl   DoneRects
  2057.  
  2058. RectScreen320 ldy  #oprInfo+orPage
  2059. RectLoop4    lda   [PrRecPtr],y
  2060.              cmp   SCrPage320-orPage-oprInfo,y
  2061.              beq   OK4
  2062.  
  2063.              pushlong #SCrPage320
  2064.              lda   <PrRecPtr
  2065.              clc
  2066.              adc   #oprInfo+orPage
  2067.              tax
  2068.              lda   <PrRecPtr+2
  2069.              adc   #0
  2070.              pha
  2071.              phx                        ; pointer to destination
  2072.              pushlong #16               ; two rects = 16 bytes
  2073.              _BlockMove
  2074.              inc   <RectChanged
  2075.              bra   DoneRects
  2076.  
  2077. OK4          iny
  2078.              iny
  2079.              cpy   #oprInfo+orPage+16
  2080.              beq   doneRects
  2081.              bra   RectLoop4
  2082.  
  2083. DoneRects    rts
  2084.  
  2085.              END
  2086.